//
//  TestNew.swift
//  TestSwift
//
//  Created by 小星星吃KFC on 2021/6/1.
//

import Foundation

func TestNew() {
    
    /// https://blog.csdn.net/weixin_33901641/article/details/93182546
    @dynamicMemberLookup
    enum JSON {
      case intValue(Int)
      case stringValue(String)
      case arrayValue(Array<JSON>)
      case dictionaryValue(Dictionary<String, JSON>)
     
      var stringValue: String? {
         if case .stringValue(let str) = self {
            return str
         }
         return nil
      }
     
      subscript(index: Int) -> JSON? {
         if case .arrayValue(let arr) = self {
            return index < arr.count ? arr[index] : nil
         }
         return nil
      }
     
      subscript(key: String) -> JSON? {
         if case .dictionaryValue(let dict) = self {
            return dict[key]
         }
         return nil
      }
     
      subscript(dynamicMember member: String) -> JSON? {
         if case .dictionaryValue(let dict) = self {
            return dict[member]
         }
         return nil
      }
    }
    
    
//    let json = JSON.stringValue("Example")
    let json = JSON.arrayValue([JSON.dictionaryValue(["name":JSON.stringValue("JIM")])])
    let srt =   json[0]?["name"]?.stringValue
  
    print("srt=\(srt)")
    
    print(json[0]?.name?.stringValue)
    
    

    /// https://www.jianshu.com/p/6a19668dd4c4
    @dynamicMemberLookup
    class JSONObject {

        var value = [String: Any]()
        
        init(_ value: [String: Any] = [:]) {
            self.value = value
        }
        subscript<T>(dynamicMember member: String)  -> T? where T: Any {
            get {
                value[member] as? T
            }
            set {
                value[member] = newValue
            }
        }
    }

    var jsonObject = JSONObject([
        "a": 1,
        "b": 2.2,
        "c": "hello"
    ])
    var a: Int? = jsonObject.a
    var b: Double? = jsonObject.b
    var c: String? = jsonObject.c
    print(a, b, c)
    // 1, 2.2, "hello"
    jsonObject.a = 55
    jsonObject.b = 66.6
    jsonObject.c = "world"
    a = jsonObject.a
    b = jsonObject.b
    c = jsonObject.c
    print(a, b, c)
    // 55, 66.6, "world"

    
    do {
        @dynamicMemberLookup
        @dynamicCallable
        class JSONObject {
            
            static var new: Self { Self() }
            
            public var value = [String: Any]()
            
            required init(_ value: [String: Any] = [:]) {
                self.value = value
            }
            
            func dynamicallyCall(withKeywordArguments args: KeyValuePairs<String, Any>) -> Self {
                for item in args {
                    value[item.0] = item.1
                }
                return self
            }
            
            subscript<T>(dynamicMember member: String) -> T where T: Any {
                get {
                    value[member] as! T
                }
                set {
                    value[member] = newValue
                }
            }
            
        }

        let dog = JSONObject.new(name: "Tom", age: 11, weight: 33.3)
        let name: String = dog.name
        let age = dog.age as Int
        let weight: Double = dog.weight
        print(name) // Tom
        print(age) // 11
        print(weight) // 33.3

    }
}
